import { createRouter, createWebHistory, RouteRecordRaw } from 'vue-router'
import pascalToCamelCase from '@util/pascalToCamelCase'
import TypeMenuItem from '@src/interfaces/TypeMenuItem'
import TypeMenuInfo from '@src/interfaces/TypeMenuInfo'
import TokenUtil from '@util/TokenUtil.ts'
import { ElMessage } from 'element-plus'

type TypeLayoutMapValue = {
  component: RouteRecordRaw
  children: RouteRecordRaw[]
} & {
  menu: TypeMenuItem[]
}

export const layoutMap = (() => {
  const layoutInfo = import.meta.glob('@src/pages/*.vue', {
    eager: true,
    import: 'default',
  })
  const _layoutMap = new Map<string, TypeLayoutMapValue>()
  Object.entries(layoutInfo).forEach(([filePath, component]) => {
    filePath = filePath.replace(/^\/src\/pages\/|\.layout\.vue$/g, '')
    filePath = pascalToCamelCase(filePath)

    _layoutMap.set(`/${filePath}`, {
      component: component as RouteRecordRaw,
      children: [],
      menu: [],
    })
  })

  const pageInfo = import.meta.glob('@src/pages/*/**/*.vue', {
    eager: true,
    import: 'default',
  })
  Object.entries(pageInfo).forEach(([filePath, component]) => {
    filePath = filePath.replace(/^\/src\/pages|\.vue$/g, '')

    const filePathPrefix = filePath.substring(0, filePath.indexOf('/', 1))
    const layout = _layoutMap.get(filePathPrefix)
    if (!layout) return

    let urlPath = ''
    filePath.split('/').forEach((word) => {
      // 动态路由
      if (/^\[(.*)]$/.test(word)) {
        word = word.replace(/^\[(.*)]$/, ':$1')
        urlPath += urlPath.endsWith('/') ? `${word}` : `/${word}`
        return
      }

      word = pascalToCamelCase(word)
      if ('index' === word) return
      urlPath += urlPath.endsWith('/') ? `${word}` : `/${word}`
    })

    layout.children.push({
      path: urlPath,
      // @ts-ignore
      component: component,
    })
    _layoutMap.set(filePathPrefix, layout)
  })

  const menuInfo = import.meta.glob('@src/pages/*/**/*.menu.ts', {
    eager: true,
    import: 'default',
  })
  const menuItemMap = new Map<string, TypeMenuItem>()
  Object.entries(menuInfo).forEach(([filePath, menu]) => {
    const menuInfo = menu as TypeMenuInfo

    filePath =
      menuInfo.path || filePath.replace(/^\/src\/pages|\.menu\.ts$/g, '')
    filePath = filePath.replace(/\/[0-9]+\./g, '/')

    let urlPath = ''
    let menuPath = ''
    filePath.split('/').forEach((word) => {
      word = pascalToCamelCase(word)
      menuPath += menuPath.endsWith('/') ? `${word}` : `/${word}`
      if ('index' === word) return
      urlPath += urlPath.endsWith('/') ? `${word}` : `/${word}`
    })

    const filePathPrefix = menuPath.substring(0, filePath.indexOf('/', 1))

    if (!_layoutMap.has(filePathPrefix)) {
      console.warn(
        `未找到’${filePathPrefix}’根路由，菜单‘${menuInfo.text}’将不会显示！`,
      )
      return
    }
    const thirdIndex = menuPath.indexOf('/', menuPath.indexOf('/', 1) + 1)
    if (thirdIndex < 0) {
      menuItemMap.set(menuPath, {
        text: menuInfo.text,
        path: urlPath,
        children: [],
      })
      return
    }

    const key = menuPath.substring(0, thirdIndex)
    const parentItem = menuItemMap.get(key)
    if (!parentItem) return
    parentItem.children ||= []
    parentItem.children.push({
      text: menuInfo.text,
      path: urlPath,
    })
    menuItemMap.set(key, parentItem)
  })
  menuItemMap.forEach((value, key) => {
    const prefix = key.substring(0, key.indexOf('/', 1))
    const layout = _layoutMap.get(prefix)
    if (!layout) return
    layout.menu.push(value)
  })

  return _layoutMap
})()

export const routes = (() => {
  const _routes: RouteRecordRaw[] = []
  layoutMap.forEach((value, key) => {
    const { component, children } = value as TypeLayoutMapValue
    _routes.push({
      path: key,
      // @ts-ignore
      component,
      children,
    })
  })
  return _routes
})()

export const router = createRouter({
  history: createWebHistory(),
  routes: routes,
})

router.beforeEach((to) => {
  if (to.path.startsWith('/login')) {
    return
  }
  if (to.path.startsWith('/register')) {
    return
  }
  const token = TokenUtil.getToken()
  if (!to.path.startsWith('/admin')) {
    if (token) return
    ElMessage.warning('需要登录！')
    return '/login'
  }

  if (!token) {
    ElMessage.warning('需要登录！')
    return '/login/admin'
  }
})

// 路由守卫
router.beforeEach((to, from) => {})

export const getAllMenu = () => {
  const allMenu: TypeMenuItem[] = []
  layoutMap.forEach(({ menu }) => {
    allMenu.push(...menu)
  })
  return allMenu
}

export const getCurrentPathMenu = () => {
  const path = window.location.pathname
  const secondIndex = path.indexOf('/', 1)
  const prefix = secondIndex < 0 ? path : path.substring(0, secondIndex)
  let layout = layoutMap.get(prefix)
  if (!layout) {
    layout = layoutMap.get('/index')
  }

  return layout?.menu || []
}
